home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagn_r.zip / POINTERS.SWG / 0005_OOP-LLST.PAS.pas < prev    next >
Pascal/Delphi Source File  |  1993-05-28  |  12KB  |  490 lines

  1. Program Linked;
  2.  
  3. Type
  4.   FileDescriptor =
  5.     Object
  6.       Fpt       : File;
  7.       Name      : String[80];
  8.       HeaderSize: Word;
  9.       RecordSize: Word;
  10.       RecordPtr : Pointer;
  11.       SoftPut   : Boolean;
  12.       IsOpen    : Boolean;
  13.       CurRec    : LongInt;
  14.  
  15.       Constructor Init(Nam : String; Hdr : Word; Size : Word; Buff : Pointer;
  16. Put : Boolean);
  17.       Destructor  Done; Virtual;
  18.       Procedure   OpenFile; Virtual;
  19.       Procedure   CloseFile; Virtual;
  20.       Procedure   GetRecord(Rec : LongInt);
  21.       Procedure   PutRecord(Rec : LongInt);
  22.     end;
  23.  
  24.   FileLable =
  25.     Record
  26.       Eof : LongInt;
  27.       MRD : LongInt;
  28.       Act : LongInt;
  29.       Val : LongInt;
  30.       Sync: LongInt;
  31.     end;
  32.  
  33.   LabeledFile =
  34.     Object(FileDescriptor)
  35.       Header : FileLable;
  36.  
  37.       Constructor Init(Nam : String; Size : Word; Buff : Pointer; Put :
  38. Boolean);
  39.       Destructor  Done; Virtual;
  40.       Procedure   OpenFile; Virtual;
  41.       Procedure   CloseFile; Virtual;
  42.       Procedure   WriteHeader;
  43.       Procedure   ReadHeader;
  44.       Procedure   AddRecord;
  45.       Procedure   DelRecord(Rec : LongInt);
  46.     end;
  47.  
  48.   DetailHeaderPtr = ^DetailHeader;
  49.   DetailHeader =
  50.     Record
  51.       Master : LongInt;
  52.       Prev   : LongInt;
  53.       Next   : LongInt;
  54.     end;
  55.  
  56.   MasterHeaderPtr = ^MasterHeader;
  57.   MasterHeader =
  58.     Record
  59.       First  : LongInt;
  60.       Last   : LongInt;
  61.     end;
  62.  
  63.   DetailFileDetailPtr = ^DetailFileDetail;
  64.   DetailFileDetail =
  65.     Object(LabeledFile)
  66.       Constructor Init(Nam : String; Size : Word; Buff : Pointer; Put :
  67. Boolean);
  68.       Procedure   LinkChain(MR, Last, Curr : LongInt);
  69.       Procedure   DelinkChain(Rec : LongInt);
  70.     end;
  71.  
  72.   DetailFileMaster =
  73.     Object(LabeledFile)
  74.       Constructor Init(Nam : String; Size : Word; Buff : Pointer; Put :
  75. Boolean);
  76.       Procedure   LinkDetail(DF : DetailFileDetailPtr);
  77.       Procedure   DelinkDetail(DF : DetailFileDetailPtr; DR : LongInt);
  78.       Procedure   GetFirst(DF : DetailFileDetailPtr);
  79.       Procedure   GetLast(DF : DetailFileDetailPtr);
  80.       Procedure   GetNext(DF : DetailFileDetailPtr);
  81.       Procedure   GetPrev(DF : DetailFileDetailPtr);
  82.     end;
  83.  
  84. {---------------------------------------------------------------------------}
  85.  
  86. Constructor FileDescriptor.Init(Nam : String; Hdr : Word; Size : Word; Buff :
  87.                                 Pointer; Put : Boolean);
  88.   begin
  89.     IsOpen := False;
  90.     Name := Nam;
  91.     HeaderSize := Hdr;
  92.     RecordSize := Size;
  93.     RecordPtr := Buff;
  94.     SoftPut := Put;
  95.     CurRec := -1;
  96.   end;
  97.  
  98. Destructor  FileDescriptor.Done;
  99.   begin
  100.     if SoftPut and (CurRec <> -1) then
  101.         PutRecord(CurRec);
  102.     if IsOpen then
  103.         CloseFile;
  104.   end;
  105.  
  106. Procedure   FileDescriptor.OpenFile;
  107.   begin
  108.     if IsOpen then
  109.         Exit;
  110.     Assign(Fpt,Name);
  111.     {$I-}
  112.     Reset(Fpt,1);
  113.     if IoResult <> 0 then
  114.         ReWrite(Fpt,1);
  115.     if IoResult = 0 then
  116.         IsOpen := True;
  117.     {$I+}
  118.     CurRec := -1;
  119.   end;
  120.  
  121. Procedure   FileDescriptor.CloseFile;
  122.   begin
  123.     if not IsOpen then
  124.         Exit;
  125.     {$I-}
  126.     Close(Fpt);
  127.     if IoResult = 0 then
  128.         IsOpen := False;
  129.     {$I+}
  130.     CurRec := -1;
  131.   end;
  132.  
  133. Procedure   FileDescriptor.GetRecord(Rec : LongInt);
  134.   Var
  135.     Result : Word;
  136.   begin
  137.     if not IsOpen then
  138.         Exit;
  139.     if CurRec = Rec then
  140.         Exit;
  141.     if SoftPut and (CurRec <> -1) then
  142.         PutRecord(CurRec);
  143.     {$I-}
  144.     if Rec = 0 then
  145.       begin
  146.         Seek(Fpt,0);
  147.         if IoResult = 0 then
  148.           begin
  149.             BlockRead(Fpt,RecordPtr^,HeaderSize,Result);
  150.             if (Result <> HeaderSize) or (IoResult <> 0) then
  151.                 {Error Routine};
  152.           end;
  153.       end
  154.     else
  155.       begin
  156.         Seek(Fpt,HeaderSize + (Rec - 1) * RecordSize);
  157.         if IoResult = 0 then
  158.           begin
  159.             BlockRead(Fpt,RecordPtr^,RecordSize,Result);
  160.             if (Result <> RecordSize) or (IoResult <> 0) then
  161.                 {Error Routine};
  162.           end;
  163.       end;
  164.     {$I+}
  165.     CurRec := Rec;
  166.   end;
  167.  
  168. Procedure   FileDescriptor.PutRecord(Rec : LongInt);
  169.   Var
  170.     Result : Word;
  171.   begin
  172.     if not IsOpen then
  173.         Exit;
  174.     {$I-}
  175.     if Rec = 0 then
  176.       begin
  177.         Seek(Fpt,0);
  178.         if IoResult = 0 then
  179.           begin
  180.             BlockWrite(Fpt,RecordPtr^,HeaderSize,Result);
  181.             if (Result <> HeaderSize) or (IoResult <> 0) then
  182.                 {Error Routine};
  183.           end;
  184.       end
  185.     else
  186.       begin
  187.         Seek(Fpt,HeaderSize + (Rec - 1) * RecordSize);
  188.         if IoResult = 0 then
  189.           begin
  190.             BlockWrite(Fpt,RecordPtr^,RecordSize,Result);
  191.             if (Result <> RecordSize) or (IoResult <> 0) then
  192.                 {Error Routine};
  193.           end;
  194.       end;
  195.     CurRec := Rec;
  196.     {$I+}
  197.   end;
  198.  
  199. {---------------------------------------------------------------------------}
  200.  
  201. Constructor LabeledFile.Init(Nam : String; Size : Word; Buff : Pointer; Put :
  202. Boolean);
  203.   begin
  204.     if Size < 4 then
  205.       begin
  206.         WriteLN('Record size must be 4 or larger');
  207.         Fail;
  208.       end;
  209.     FileDescriptor.Init(Nam,Sizeof(Header),Size,Buff,Put);
  210.     Header.Eof := 0;
  211.     Header.MRD := 0;
  212.     Header.Act := 0;
  213.     Header.Val := 0;
  214.     Header.Sync:= 0;
  215.   end;
  216.  
  217. Destructor LabeledFile.Done;
  218.   begin
  219.     CloseFile;
  220.     FileDescriptor.Done;
  221.   end;
  222.  
  223. Procedure LabeledFile.OpenFile;
  224.   begin
  225.     FileDescriptor.OpenFile;
  226.     if IsOpen then
  227.         ReadHeader;
  228.   end;
  229.  
  230. Procedure LabeledFile.CloseFile;
  231.   begin
  232.     {$I-}
  233.     if IsOpen then
  234.       begin
  235.         if SoftPut and (CurRec <> -1) then
  236.             PutRecord(CurRec);
  237.         Header.Val := 0;
  238.         WriteHeader;
  239.         CurRec := -1;
  240.       end;
  241.     FileDescriptor.CloseFile;
  242.     {$I+}
  243.   end;
  244.  
  245. Procedure LabeledFile.ReadHeader;
  246.   Var
  247.     Result : Word;
  248.   begin
  249.     {$I-}
  250.     Seek(Fpt,0);
  251.     if IoResult = 0 then
  252.       begin
  253.         BlockRead(Fpt,Header,HeaderSize,Result);
  254.         if (Result <> HeaderSize) or (IoResult <> 0) then
  255.             {Error Routine};
  256.       end;
  257.     {$I+}
  258.   end;
  259.  
  260. Procedure LabeledFile.WriteHeader;
  261.   Var
  262.     Result : Word;
  263.   begin
  264.     {$I-}
  265.     Seek(Fpt,0);
  266.     if IoResult = 0 then
  267.       begin
  268.         BlockWrite(Fpt,Header,HeaderSize,Result);
  269.         if (Result <> HeaderSize) or (IoResult <> 0) then
  270.             {Error Routine};
  271.       end;
  272.     {$I+}
  273.   end;
  274.  
  275. Procedure LabeledFile.AddRecord;
  276.   Var
  277.     TmpRec : Pointer;
  278.     Result : Word;
  279.     Next   : LongInt;
  280.   begin
  281.     {$I-}
  282.     if Header.MRD <> 0 then
  283.       begin
  284.         GetMem(TmpRec,RecordSize);
  285.         Seek(Fpt,HeaderSize + (Header.MRD - 1) * RecordSize);
  286.         if IoResult = 0 then
  287.           begin
  288.             BlockRead(Fpt,TmpRec^,RecordSize,Result);
  289.             if (Result <> RecordSize) or (IoResult <> 0) then
  290.                 {Error Routine};
  291.             Next := LongInt(TmpRec^);
  292.             PutRecord(Header.MRD);
  293.             Header.MRD := Next;
  294.             Header.Act := Header.Act + 1;
  295.           end;
  296.         FreeMem(TmpRec,RecordSize);
  297.       end
  298.     else
  299.       begin
  300.         PutRecord(Header.Eof);
  301.         Header.Eof := Header.Eof + 1;
  302.         Header.Act := Header.Act + 1;
  303.       end;
  304.     WriteHeader;
  305.     {$I+}
  306.   end;
  307.  
  308. Procedure LabeledFile.DelRecord(Rec : LongInt);
  309.   Var
  310.     TmpRec : Pointer;
  311.     Result : Word;
  312.   begin
  313.     {$I-}
  314.     GetMem(TmpRec,RecordSize);
  315.     Seek(Fpt,HeaderSize + (Rec - 1) * RecordSize);
  316.     if IoResult = 0 then
  317.       begin
  318.         BlockRead(Fpt,TmpRec^,RecordSize,Result);
  319.         LongInt(TmpRec^) := Header.MRD;
  320.         BlockWrite(Fpt,TmpRec^,RecordSize,Result);
  321.         if (Result <> RecordSize) or (IoResult <> 0) then
  322.            {Error Routine};
  323.         Header.MRD := Rec;
  324.         Header.Act := Header.Act - 1;
  325.         WriteHeader;
  326.       end;
  327.     {$I+}
  328.   end;
  329.  
  330. {---------------------------------------------------------------------------}
  331.  
  332. Constructor DetailFileDetail.Init(Nam : String; Size : Word; Buff : Pointer;
  333. Put : Boolean);
  334.   begin
  335.     if Size < 12 then
  336.       begin
  337.         WriteLn('Detail File Records must be 12 Bytes or more');
  338.         Fail;
  339.       end;
  340.     LabeledFile.Init(Nam,Size,Buff,Put);
  341.   end;
  342.  
  343. Procedure   DetailFileDetail.LinkChain(MR, Last, Curr : LongInt);
  344.   Var
  345.     Hdr : DetailHeaderPtr;
  346.   begin
  347.     Hdr := RecordPtr;
  348.     if Last <> 0 then
  349.       begin
  350.         GetRecord(Last);
  351.         Hdr^.Next := Curr;
  352.         PutRecord(Last);
  353.       end;
  354.     GetRecord(Curr);
  355.     Hdr^.Prev := Last;
  356.     Hdr^.Master := MR;
  357.     Hdr^.Next := 0;
  358.     PutRecord(Curr);
  359.   end;
  360.  
  361. Procedure   DetailFileDetail.DelinkChain(Rec : LongInt);  Var
  362.     Hdr : DetailHeaderPtr;
  363.     Tmp : LongInt;
  364.   begin
  365.     Hdr := RecordPtr;
  366.     GetRecord(Rec);
  367.     if Hdr^.Next <> 0 then
  368.       begin
  369.         Tmp := Hdr^.Prev;
  370.         GetRecord(Hdr^.Next);
  371.         Hdr^.Prev := Tmp;
  372.         PutRecord(CurRec);
  373.         GetRecord(Rec);
  374.       end;
  375.     if Hdr^.Prev <> 0 then
  376.       begin
  377.         Tmp := Hdr^.Next;
  378.         GetRecord(Hdr^.Prev);
  379.         Hdr^.Next := Tmp;
  380.         PutRecord(CurRec);
  381.         GetRecord(Rec);
  382.       end;
  383.     Hdr^.Master := 0;
  384.     Hdr^.Next := 0;
  385.     Hdr^.Prev := 0;
  386.     PutRecord(Rec);
  387.   end;
  388.  
  389. {---------------------------------------------------------------------------}
  390.  
  391. Constructor DetailFileMaster.Init(Nam : String; Size : Word; Buff : Pointer;
  392. Put : Boolean);
  393.   begin
  394.     if Size < 8 then
  395.       begin
  396.         WriteLn('Master File Records must be 8 Bytes or more');
  397.         Fail;
  398.       end;
  399.     LabeledFile.Init(Nam,Size,Buff,Put);
  400.   end;
  401.  
  402. Procedure   DetailFileMaster.LinkDetail(DF : DetailFileDetailPtr);
  403.   Var
  404.     Hdr : MasterHeaderPtr;
  405.   begin
  406.     Hdr := RecordPtr;
  407.     DF^.AddRecord;
  408.     DF^.LinkChain(CurRec,Hdr^.Last,DF^.CurRec);
  409.     Hdr^.Last := DF^.CurRec;
  410.     if Hdr^.First = 0 then Hdr^.First := DF^.CurRec;
  411.     PutRecord(CurRec);
  412.   end;
  413.  
  414. Procedure   DetailFileMaster.DelinkDetail(DF : DetailFileDetailPtr; DR :
  415. LongInt);
  416.   Var
  417.     Hdr : MasterHeaderPtr;
  418.   begin
  419.     Hdr := RecordPtr;
  420.     DF^.GetRecord(DR);
  421.     if Hdr^.Last = DR then
  422.         Hdr^.Last := DetailHeader(DF^.RecordPtr^).Prev;
  423.     if Hdr^.First = DR then
  424.         Hdr^.First := DetailHeader(DF^.RecordPtr^).Next;
  425.     DF^.DelinkChain(DR);
  426.     PutRecord(CurRec);
  427.   end;
  428.  
  429. Procedure   DetailFileMaster.GetFirst(DF : DetailFileDetailPtr);
  430.   Var
  431.     Hdr : MasterHeaderPtr;
  432.   begin
  433.     Hdr := RecordPtr;
  434.     if Hdr^.First = 0 then
  435.       begin
  436.         FillChar(DF^.RecordPtr^,DF^.RecordSize,#0);
  437.         DF^.CurRec := -1;
  438.         Exit;
  439.       end;
  440.     DF^.GetRecord(Hdr^.First);
  441.   end;
  442.  
  443. Procedure   DetailFileMaster.GetLast(DF : DetailFileDetailPtr);
  444.   Var
  445.     Hdr : MasterHeaderPtr;
  446.   begin
  447.     Hdr := RecordPtr;
  448.     if Hdr^.Last = 0 then
  449.       begin
  450.         FillChar(DF^.RecordPtr^,DF^.RecordSize,#0);
  451.         DF^.CurRec := -1;
  452.         Exit;
  453.       end;
  454.     DF^.GetRecord(Hdr^.Last);
  455.   end;
  456.  
  457. Procedure   DetailFileMaster.GetNext(DF : DetailFileDetailPtr);
  458.   Var
  459.     Hdr : DetailHeaderPtr;
  460.   begin
  461.     Hdr := DF^.RecordPtr;
  462.     if Hdr^.Next = 0 then
  463.       begin
  464.         FillChar(DF^.RecordPtr^,DF^.RecordSize,#0);
  465.         DF^.CurRec := -1;
  466.         Exit;
  467.       end;
  468.     DF^.GetRecord(Hdr^.Next);
  469.   end;
  470.  
  471. Procedure   DetailFileMaster.GetPrev(DF : DetailFileDetailPtr);
  472.   Var
  473.     Hdr : DetailHeaderPtr;
  474.   begin
  475.     Hdr := DF^.RecordPtr;
  476.     if Hdr^.Prev = 0 then
  477.       begin
  478.         FillChar(DF^.RecordPtr^,DF^.RecordSize,#0);
  479.         DF^.CurRec := -1;
  480.         Exit;
  481.       end;
  482.     DF^.GetRecord(Hdr^.Prev);
  483.   end;
  484.  
  485. {---------------------------------------------------------------------------}
  486.  
  487. begin
  488. end.
  489.  
  490.